package com.fhd.servlet;

import com.fhd.constant.Constants;
import com.fhd.pojo.*;
import com.fhd.service.Bill.BillService;
import com.fhd.service.Bill.BillServiceImplement;
import com.fhd.service.Client.ClientService;
import com.fhd.service.Client.ClientServiceImplement;
import com.fhd.service.House.HouseService;
import com.fhd.service.House.HouseServiceImplement;
import com.fhd.service.Merchant.MerchantService;
import com.fhd.service.Merchant.MerchantServiceImplement;
import com.fhd.service.Recharge.RechargeService;
import com.fhd.service.Recharge.RechargeServiceImplement;
import com.fhd.utils.DateTimeUtil;
import com.mysql.cj.util.StringUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Date;
import java.sql.SQLException;
import java.time.Period;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Random;

public class ClientServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getParameter("method");
        if (Objects.equals(method,"clientUpdateInformation")) {
            updateInformation(req,resp);
        } else if (Objects.equals(method,"getPoints")) {
            getPoints(req, resp);
        } else if (Objects.equals(method,"clientRecharge")) {
            clientRecharge(req, resp);
        } else if (Objects.equals(method,"getSomeoneRecharges")) {
            getSomeoneRecharge(req, resp);
        } else if (Objects.equals(method,"clientLogout")) {
            clientLogout(req, resp);
        } else if (Objects.equals(method,"getAllMerchant")) {
            getAllMerchant(req, resp);
        } else if (Objects.equals(method,"selectShopName")) {
            selectShopName(req, resp);
        } else if (Objects.equals(method,"orderMerchant")) {
            orderMerchant(req, resp);
        } else if (Objects.equals(method,"getMerchantInformationAndHouse")) {
            getMerchantInformationAndHouse(req, resp);
        } else if (Objects.equals(method,"closeClientVisitMerchantSession")) {
            closeClientVisitMerchantSession(req, resp);
        } else if (Objects.equals(method,"clientPlaceOrder")) {
            try {
                clientPlaceOrder(req, resp);
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        } else if (Objects.equals(method,"getClientBill")) {
            getClientBill(req,resp);
        } else if (Objects.equals(method,"clientCancelBill")) {
            try {
                clientCancelBill(req, resp);
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    // 修改客户信息
    public void updateInformation(HttpServletRequest req, HttpServletResponse resp) {
        try {
            Object object = req.getSession().getAttribute(Constants.CLIENT_SESSION);
            int row = 0;
            if (object != null) {
                Client client = (Client) object;
                int id = client.getId();
                String userCode = req.getParameter("userCode");
                String userPassword = req.getParameter("userPassword");
                String userName = req.getParameter("userName");
                if (StringUtils.isNullOrEmpty(userCode) && StringUtils.isNullOrEmpty(userPassword) && StringUtils.isNullOrEmpty(userName)) {
                    // 不会写JS嘻嘻 只好在这里判断 效果还是很不错的
                    req.getSession().setAttribute(Constants.UPDATE_MESSAGE,"请至少改动一项信息");
                    resp.sendRedirect("jsp/clientUpdateInformation.jsp");
                } else {
                    ClientService clientService = new ClientServiceImplement();
                    row = clientService.updateInformation(id, userCode, userPassword, userName);

                    if (row > 0) {
                        // 更改成功，返回成功信息，回到登录页
                        req.getSession().setAttribute(Constants.UPDATE_MESSAGE,"修改成功");
                        resp.sendRedirect("login.jsp");
                    } else {
                        // 更改失败或者无法得到客户id，返回失败信息，回到修改信息页
                        req.getSession().setAttribute(Constants.UPDATE_MESSAGE,"修改失败");
                        resp.sendRedirect("jsp/clientUpdateInformation.jsp");
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    // 签到领取积分
    public void getPoints(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object object = req.getSession().getAttribute(Constants.CLIENT_SESSION);
        if (object != null) {
            Client client = (Client) object;

            Date lastDate = client.getLastPointsDate();
            Date newDate = DateTimeUtil.getNowDate();

            // 如果上次签到时间和本次时间相差一天，则可以签到，或者这是第一次签到
            if (Period.between(lastDate.toLocalDate(),newDate.toLocalDate()).getDays() >= 1) {
                // 调用业务层
                ClientService clientService = new ClientServiceImplement();
                int id = client.getId();
                // 生成1~100的随机数并加上之前的积分
                int points = new Random().nextInt(100) + 1 + client.getPoints();
                int row = clientService.updateLastPointsDate(id, points, newDate);

                if (row > 0) {
                    // 更改成功，将用户新的信息放进session中，回到主页
                    client.setPoints(points);
                    client.setLastPointsDate(newDate);
                    req.getSession().setAttribute(Constants.CLIENT_SESSION,client);
                    resp.sendRedirect("jsp/clientFrame.jsp");
                } else {
                    // 更改失败，让用户重试
                    req.getSession().setAttribute(Constants.GET_POINTS_MESSAGE,"更改失败请重试");
                    resp.sendRedirect("jsp/clientFrame.jsp");
                }
            } else {
                // 告知用户今天已经签到了
                req.getSession().setAttribute(Constants.GET_POINTS_MESSAGE,"（今天已经签过了,明天再来叭~）");
                resp.sendRedirect("jsp/clientFrame.jsp");
            }

        }
    }

    // 充值
    public void clientRecharge(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object object = req.getSession().getAttribute(Constants.CLIENT_SESSION);
        if (object != null) {
            Client client = (Client) object;
            // 获取前端传来的充值的数目
            String parameter = req.getParameter("money");
            int money = Integer.parseInt(parameter);
            // 从session中获取id
            int id = client.getId();
            // 调用业务层
            RechargeService rechargeService = new RechargeServiceImplement();
            int row = rechargeService.clientRecharge(money, id);

            if (row > 0) {
                // 创建充值成功，提醒用户需要等待管理员确认
                req.getSession().setAttribute(Constants.CLIENT_RECHARGE_MESSAGE,"操作成功，请等待管理员审核");
                resp.sendRedirect("client.do?method=getSomeoneRecharges");
            } else {
                // 创建充值数据失败
                req.getSession().setAttribute(Constants.CLIENT_RECHARGE_MESSAGE,"操作失败请重试");
                resp.sendRedirect("client.do?method=getSomeoneRecharges");
            }
        }

    }

    // 展示该客户所有的充值数据,并更新余额
    public void getSomeoneRecharge(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object object = req.getSession().getAttribute(Constants.CLIENT_SESSION);
        if (object != null) {
            // 获取数据
            Client client = (Client) object;
            int id = client.getId();

            // 调用业务层更新余额
            ClientService clientService = new ClientServiceImplement();
            int money = clientService.getMoney(id);
            // 判断是否有误
            if (money >= 0) {
                client.setMoney(money);
                req.getSession().setAttribute(Constants.CLIENT_SESSION,client);
            }


            // 调用业务层获取充值数据
            RechargeService rechargeService = new RechargeServiceImplement();
            ArrayList<Recharge> recharges = rechargeService.getSomeoneRecharge(id);

            // 判断是否有充值数据
            if (recharges != null && !recharges.isEmpty()) {
                // 把recharges放进session中
                req.getSession().setAttribute(Constants.SOMEONE_RECHARGE_SESSION,recharges);
                // 回到钱包页，在前端显示充值记录
                resp.sendRedirect("jsp/clientWallet.jsp");
            } else {
                // 返会信息显示暂无充值记录
                req.getSession().setAttribute(Constants.GET_SOMEONE_RECHARGE_MESSAGE,"暂无充值记录，请充值先噢~");
                resp.sendRedirect("jsp/clientWallet.jsp");
            }
        }
    }

    // 退出客户登录
    public void clientLogout(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        req.getSession().removeAttribute(Constants.CLIENT_SESSION);
        resp.sendRedirect("login.jsp");
    }

    //获取所有的商户信息
    public void getAllMerchant(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 调用业务层
        MerchantService merchantService = new MerchantServiceImplement();
        ArrayList<Merchant> merchants = merchantService.getAllMerchant();

        if (merchants != null && !merchants.isEmpty()) {
            // 把商户放进Session中
            req.getSession().setAttribute(Constants.GET_MERCHANT_SESSION,merchants);
        } else {
            // 还没有商户注册，空空如也
            req.getSession().setAttribute(Constants.GET_MERCHANT_MESSAGE,"还没有商户注册噢，空空如也~");
        }
        // 前往我要订房页
        resp.sendRedirect("jsp/clientBookHouse.jsp");
    }

    // 模糊查询店铺
    public void selectShopName(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String shopName = req.getParameter("shopName");
        // 调用业务层
        MerchantService merchantService = new MerchantServiceImplement();
        ArrayList<Merchant> merchants = merchantService.getSomeMerchant(shopName);

        if (merchants != null && !merchants.isEmpty()) {
            // 把商户放进Session中
            req.getSession().setAttribute(Constants.GET_MERCHANT_SESSION,merchants);
        } else {
            // 还没有商户注册，空空如也
            req.getSession().setAttribute(Constants.GET_MERCHANT_MESSAGE,"找不到你要的用户");
        }
        // 前往我要订房页
        resp.sendRedirect("jsp/clientBookHouse.jsp");
    }

    // 排序商户信息
    public void orderMerchant(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取参数
        String soldNumberOrder = req.getParameter("soldNumberOrder");
        String createDateOrder = req.getParameter("createDateOrder");

        if (Objects.equals(soldNumberOrder,"null") && Objects.equals(createDateOrder,"null")) {
            // 需要搜索的两个条件都为null, 返回错误信息
            req.getSession().setAttribute(Constants.ORDER_MESSAGE,"请至少选择一项条件进行排序");
        } else {
            // 调用业务层
            MerchantService merchantService = new MerchantServiceImplement();
            ArrayList<Merchant> merchants = merchantService.orderMerchant(soldNumberOrder,createDateOrder);

            if (merchants != null && !merchants.isEmpty()) {
                // 把商户放进Session中
                req.getSession().setAttribute(Constants.GET_MERCHANT_SESSION,merchants);
            } else {
                // 还没有商户注册，空空如也
                req.getSession().setAttribute(Constants.GET_MERCHANT_MESSAGE,"还没有商户注册噢，空空如也~");
            }
        }
        // 前往我要订房页
        resp.sendRedirect("jsp/clientBookHouse.jsp");
    }

    // 得到某个商户的所有信息和其下的所有房型
    public void getMerchantInformationAndHouse(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        int merchantId = Integer.parseInt(req.getParameter("merchantId"));

        // 得到所有信息
        MerchantService merchantService = new MerchantServiceImplement();
        Merchant merchant = merchantService.getMerchantById(merchantId);

        // 得到该商户的所有房型
        HouseService houseService = new HouseServiceImplement();
        ArrayList<House> houses = houseService.getSomeoneHouse(merchantId);

        // 把商户放进Session中
        req.getSession().setAttribute(Constants.CLIENT_VISIT_MERCHANT_INFORMATION_SESSION,merchant);

        if (houses.isEmpty()) {
            // 该商户没有房型
            req.getSession().setAttribute(Constants.CLIENT_VISIT_MERCHANT_MESSAGE,"该商户暂且没有房型，下次再来吧qwq");
        } else {
            // 有房型，放进Session中
            req.getSession().setAttribute(Constants.CLIENT_VISIT_MERCHANT_HOUSE_SESSION,houses);
        }

        // 跳转页面
        resp.sendRedirect("jsp/clientVisitMerchant.jsp");
    }

    // 从商户信息页返回的时候把相关Session关掉
    public void closeClientVisitMerchantSession(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        req.getSession().removeAttribute(Constants.CLIENT_VISIT_MERCHANT_INFORMATION_SESSION);
        req.getSession().removeAttribute(Constants.CLIENT_VISIT_MERCHANT_HOUSE_SESSION);
        resp.sendRedirect("client.do?method=getAllMerchant");
    }

    // 客户下单
    public void clientPlaceOrder(HttpServletRequest req, HttpServletResponse resp) throws IOException, SQLException {
        // 接受所有参数
        int clientId = Integer.parseInt(req.getParameter("clientId"));
        int merchantId = Integer.parseInt(req.getParameter("merchantId"));
        int houseId = Integer.parseInt(req.getParameter("houseId"));
        int number = Integer.parseInt(req.getParameter("number"));
        int price = Integer.parseInt(req.getParameter("price"));
        Date startTime = Date.valueOf(req.getParameter("startTime"));
        Date endTime = Date.valueOf(req.getParameter("endTime"));
        // 判断余额够不够
        if(((Client)req.getSession().getAttribute(Constants.CLIENT_SESSION)).getMoney() < price * number) {
            // 钱不够，无法下单
            req.getSession().setAttribute(Constants.CLIENT_PLACE_ORDER_MESSAGE,"余额不足，请充值先噢");
        } else {
            // 钱够了
            BillService billService = new BillServiceImplement();
            int row = billService.clientPlaceOrder(clientId, merchantId, houseId, price * number, number, startTime, endTime);
            // 判断业务结果
            if (row != 5) {
                // 事务有问题
                req.getSession().setAttribute(Constants.CLIENT_PLACE_ORDER_MESSAGE,"出错了");
            } else {
                //成功
                req.getSession().setAttribute(Constants.CLIENT_PLACE_ORDER_MESSAGE,"下单成功");
            }
        }
        resp.sendRedirect("client.do?method=getAllMerchant");
    }

    // 获取该客户的所有订单
    public void getClientBill(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        Object object = req.getSession().getAttribute(Constants.CLIENT_SESSION);
        if (object != null) {
            Client client = (Client) object;
            int id = client.getId();

            // 调用业务层
            BillService billService = new BillServiceImplement();
            ArrayList<Bill> bills = billService.getClientBill(id);

            if (bills.isEmpty()) {
                // 传信息
                req.getSession().setAttribute(Constants.CLIENT_BILL_MESSAGE,"没有订单数据，请下单先噢");
            } else {
                // 放进Session中，跳转页面
                req.getSession().setAttribute(Constants.CLIENT_BILL_SESSION,bills);
            }
            resp.sendRedirect("jsp/clientBill.jsp");
        }
    }

    // 客户取消订单
    public void clientCancelBill(HttpServletRequest req, HttpServletResponse resp) throws IOException, SQLException {
        // 从前端获取参数
        int billId = Integer.parseInt(req.getParameter("billId"));
        int clientId = Integer.parseInt(req.getParameter("clientId"));
        int merchantId = Integer.parseInt(req.getParameter("merchantId"));
        int houseId = Integer.parseInt(req.getParameter("houseId"));
        int money = Integer.parseInt(req.getParameter("money"));
        int number = Integer.parseInt(req.getParameter("number"));

        String parameter = req.getParameter("situation");

        if (Objects.equals(parameter,"取消订单")) {
            int situation = 4;
            // 调用业务层
            BillService billService = new BillServiceImplement();
            int row = billService.cancelBill(billId,clientId,merchantId,houseId,money,number,situation);
            if (row == 5) {
                // 更改成功
                req.getSession().setAttribute(Constants.CLIENT_CANCEL_BILL_MESSAGE,"取消成功");
            } else {
                // 更改失败
                req.getSession().setAttribute(Constants.CLIENT_CANCEL_BILL_MESSAGE,"取消失败");
            }
        }
        resp.sendRedirect("client.do?method=getClientBill");
    }
}
